using MediatR;
using SumerCoreDevOps.Application.Statistics.Queries;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Infrastructure.Data;
using SumerCoreDevOps.Shared.Models;
using TaskStatus = SumerCoreDevOps.Shared.Enums.TaskStatus;

namespace SumerCoreDevOps.Application.Statistics.Handlers;

/// <summary>
/// 获取构建趋势处理器
/// </summary>
public class GetBuildTrendQueryHandler : IRequestHandler<GetBuildTrendQuery, List<BuildTrendData>>
{
    private readonly FreeSQLProvider _dbProvider;

    public GetBuildTrendQueryHandler(FreeSQLProvider dbProvider)
    {
        _dbProvider = dbProvider;
    }

    public async Task<List<BuildTrendData>> Handle(GetBuildTrendQuery request, CancellationToken cancellationToken)
    {
        var days = request.Days > 0 ? request.Days : 7;
        var startDate = DateTime.UtcNow.Date.AddDays(-days + 1);
        var endDate = DateTime.UtcNow.Date.AddDays(1);

        // 获取指定时间范围内的所有实例
        var instances = await _dbProvider.Orm.Select<PipelineInstance>()
            .Where(p => p.CreatedAt >= startDate && p.CreatedAt < endDate)
            .ToListAsync(cancellationToken);

        // 按日期分组统计
        var trendData = new List<BuildTrendData>();
        for (int i = 0; i < days; i++)
        {
            var date = startDate.AddDays(i);
            var nextDate = date.AddDays(1);

            var dayInstances = instances
                .Where(p => p.CreatedAt >= date && p.CreatedAt < nextDate)
                .ToList();

            var successCount = dayInstances.Count(p => p.Status == TaskStatus.Success);
            var failedCount = dayInstances.Count(p => p.Status == TaskStatus.Failed);
            var cancelledCount = dayInstances.Count(p => p.Status == TaskStatus.Cancelled);

            var completedInstances = dayInstances
                .Where(p => p.StartTime.HasValue && p.EndTime.HasValue)
                .ToList();

            var avgDuration = completedInstances.Any()
                ? completedInstances.Average(p => (p.EndTime!.Value - p.StartTime!.Value).TotalMinutes)
                : 0;

            trendData.Add(new BuildTrendData
            {
                Date = date.ToString("yyyy-MM-dd"),
                SuccessCount = successCount,
                FailedCount = failedCount,
                CancelledCount = cancelledCount,
                AvgDurationMinutes = Math.Round(avgDuration, 1)
            });
        }

        return trendData;
    }
}
